home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 12
/
Amiga Format AFCD12 (Apr 1997, Issue 96).iso
/
-in_the_mag-
/
emulation
/
fs1541
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-02-09
|
5KB
|
220 lines
/*
FS1541
main.c
The handler entry point.
*/
#include <string.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/filehandler.h>
#include <utility/utility.h>
#include <devices/timer.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include "main.h"
#include "packet.h"
#include "disk.h"
#include "volume.h"
#include "support.h"
char verstring[] = "$VER: 1541-handler 1.0 (20.1.97)";
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct UtilityBase *UtilityBase, *__UtilityBase;
struct Task *ourtask;
struct MsgPort *ourport;
struct FileSysStartupMsg *fssm;
static BOOL MakeFSSM(BSTR);
/*-------------------------------------------------------------------------*/
void entry(void)
{
struct DosPacket *startuppacket;
struct DosList *devnode;
LONG error = ERROR_NO_FREE_STORE;
SysBase = *(volatile APTR*)4;
ourtask = FindTask(NULL);
ourport = &((struct Process *)ourtask)->pr_MsgPort;
WaitPort(ourport);
startuppacket = GetPacket(ourport);
devnode = (struct DosList*)BADDR(startuppacket->dp_Arg3);
if((DOSBase = (struct DosLibrary*)OpenLibrary(DOSNAME, 37)))
{
if((UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library",37)))
{
__UtilityBase = UtilityBase;
/* I'm almost sure that using the MountList `Control' field
instead of `Startup' is better; well... next time ;-) */
if(MakeFSSM(startuppacket->dp_Arg2))
{
devnode->dol_misc.dol_handler.dol_Startup = (BPTR)MKBADDR(fssm);
if(!(error = InitDiskSS(&((STRPTR)BADDR(fssm->fssm_Device))[1],fssm->fssm_Unit,fssm->fssm_Flags)))
{
if(!(error = InitVolumeSS()))
{
ULONG pktsig = 1<<(ourport->mp_SigBit);
ULONG diskchgsig = 1<<diskchgintbit;
ULONG udssig = 1<<(UDStimer->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
ULONG mask = pktsig|diskchgsig|udssig;
error = 0;
devnode->dol_Task = ourport;
ReturnPacket(startuppacket, DOSTRUE, 0);
DoDiskInsert();
for(;;)
{
ULONG sigs;
while(!( SetSignal(0,0)&mask || LoadDisk() ));
sigs = Wait(mask);
if(sigs & pktsig)
DoPackets();
if(sigs & udssig)
UpdateDiskStructure();
if(sigs & diskchgsig)
{
if(!inhibited)
{
/* We do the remove for security reasons */
DoDiskRemove();
DoDiskInsert();
}
}
}
QuitVolumeSS();
}
QuitDiskSS();
}
} else error = ERROR_REQUIRED_ARG_MISSING;
CloseLibrary((struct Library*)UtilityBase);
}
CloseLibrary((struct Library*)DOSBase);
}
if(error)
ReturnPacket(startuppacket, DOSFALSE, error);
}
static BOOL MakeFSSM(BSTR startup)
{
UBYTE str[258];
STRPTR src = BADDR(startup);
struct RDArgs *rdargs;
if(src)
{
int i,len = src[0];
/* Convert startup string */
CopyMem(&src[1], str, len);
str[len] = '\n';
str[len+1] = '\0';
for(i=0;i<len;i++)
if(str[i] == '"') str[i] = ' ';
if((rdargs = (struct RDArgs*)AllocDosObject(DOS_RDARGS, NULL)))
{
static char template[]=
"D=DEVICE/A,"
"U=UNIT/N/A,"
"F=FLAGS/N,"
"NS=NOAUTOSCAN/S"
"I=INTERLEAVE/N";
ULONG argarray[5];
rdargs->RDA_Flags |= RDAF_NOPROMPT;
rdargs->RDA_Source.CS_Buffer = str;
rdargs->RDA_Source.CS_Length = strlen(str);
rdargs->RDA_Source.CS_CurChr = 0;
if(ReadArgs(template, &argarray[0], rdargs))
{
if((fssm = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC)))
{
struct DosEnvec *env;
STRPTR name;
if((env = AllocVec(sizeof(struct DosEnvec), MEMF_PUBLIC|MEMF_CLEAR)))
{
if((name = AllocVec(strlen((STRPTR)argarray[0])+2, MEMF_PUBLIC)))
{
strcpy(name+1, (STRPTR)argarray[0]);
name[0] = strlen(name+1);
fssm->fssm_Unit = *(ULONG*)argarray[1];
fssm->fssm_Device = (BPTR)MKBADDR(name);
fssm->fssm_Flags = argarray[2] ? *(ULONG*)argarray[2] : 16;
fssm->fssm_Environ = (BPTR)MKBADDR(env);
/* These might be strange settings, but we must announce
the device as one single track with 683 sectors, other-
wise there would be some trouble with formatting etc. */
env->de_TableSize = 19;
env->de_SizeBlock = 256/4;
env->de_Surfaces = 1;
env->de_SectorPerBlock = 1;
env->de_BlocksPerTrack = 683;
env->de_LowCyl = 0;
env->de_HighCyl = 0;
env->de_DosType = ID_DOS_DISK;
env->de_MaxTransfer = 256*683;
env->de_Mask = 0x7ffffffe;
env->de_NumBuffers = 683;
env->de_Reserved = 1;
if(argarray[3])
autoscan = FALSE;
if(argarray[4])
{
LONG i = *(ULONG*)argarray[4];
if(i>0)
interleave = i;
}
return(TRUE);
}
FreeVec(fssm);
}
FreeVec(fssm);
}
FreeArgs(rdargs);
}
FreeDosObject(DOS_RDARGS, rdargs);
}
}
return(FALSE);
}